#include "stdafx.h"
#include "log/splitterchannel.hpp"
#include "log/logregistry.hpp"
#include "stream/stringtokenizer.hpp"
using JHCPP::stream::CStringTokenizer;

namespace JHCPP
{
	namespace log
	{
		CSplitterChannel::CSplitterChannel()
		{
		}

		CSplitterChannel::~CSplitterChannel()
		{
			try
			{
				close();
			}
			catch (...)
			{
				jh_unexpected();
			}
		}

		void CSplitterChannel::addChannel(CChannel* pChannel)
		{
			jh_check_ptr (pChannel);

			CMutex::ScopedLock lock(m_mutex);

			pChannel->add();
			m_channels.push_back(pChannel);
		}

		void CSplitterChannel::removeChannel(CChannel* pChannel)
		{
			CMutex::ScopedLock lock(m_mutex);

			for (ChannelVec::iterator it = m_channels.begin(); it != m_channels.end(); ++it)
			{
				if (*it == pChannel)
				{
					pChannel->release();
					m_channels.erase(it);
					break;
				}
			}
		}

		void CSplitterChannel::setProperty(const std::string& name, const std::string& value)
		{
			if (name.compare(0, 7, "channel") == 0)
			{
				CStringTokenizer tokenizer(value, ",;", CStringTokenizer::TOK_IGNORE_EMPTY | CStringTokenizer::TOK_TRIM);
				for (CStringTokenizer::Iterator it = tokenizer.begin(); it != tokenizer.end(); ++it)
				{
					addChannel(CLogRegistry::defaultRegistry().channelForName(*it));
				}
			}
			else CChannel::setProperty(name, value);
		}

		void CSplitterChannel::log(const CMessage& msg)
		{
			CMutex::ScopedLock lock(m_mutex);

			for (ChannelVec::iterator it = m_channels.begin(); it != m_channels.end(); ++it)
			{
				(*it)->log(msg);
			}
		}

		void CSplitterChannel::close()
		{
			CMutex::ScopedLock lock(m_mutex);

			for (ChannelVec::iterator it = m_channels.begin(); it != m_channels.end(); ++it)
			{
				(*it)->release();
			}
			m_channels.clear();
		}

		int CSplitterChannel::count() const
		{
			CMutex::ScopedLock lock(m_mutex);

			return (int) m_channels.size();
		}

	}//end of namespace log
}//end of namespace JHCPP
